import { Button, message, Popconfirm } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import {
  type ActionType,
  type ProColumns,
  type ProCoreActionType,
  ProTable,
} from '@ant-design/pro-components';
import React, { ReactNode, useRef } from 'react';
import { IdInfo } from '@/interfaces/common';
import type { ToolBarProps } from '@ant-design/pro-table/es/components/ToolBar';

export type ProTableProps<T> = {
  tableTitle: string,
  customCols: ProColumns<T>[],
  operationRender: (dom: React.ReactNode, entity: T, index: number, action: ProCoreActionType | undefined, schema: any) => React.ReactNode | {
    children: React.ReactNode;
    props: any;
  },
  toolBarRender: ToolBarProps<T>['toolBarRender'] | false,
  listRequest: (data:any) => any
}

export function useProTable<T extends IdInfo>(
  props: ProTableProps<T>
) {
  const {tableTitle, customCols, operationRender, toolBarRender, listRequest} = props;

  // @ts-ignore
  const columns: ProColumns<T>[] = [
    {
      dataIndex: 'index',
      valueType: 'indexBorder',
      width: 48,
    },
    ...customCols,
    {
      title: '创建时间',
      key: 'showTime',
      dataIndex: 'createdAt',
      valueType: 'fromNow',
      sorter: true,
      hideInSearch: true,
    },
    {
      title: '创建人',
      dataIndex: 'createdBy',
      sorter: true,
    },
    {
      title: '创建时间',
      dataIndex: 'createdAt',
      valueType: 'dateRange',
      hideInTable: true,
      search: {
        transform: (value) => {
          if (value) {
            return {
              createdAt: new Date(value[0]).getTime() + " - " + new Date(value[1]).getTime()
            }
          }
          return {};
        },
      },
    },
    {
      title: '操作',
      valueType: 'option',
      key: 'option',
      render: operationRender
    },
  ];

  const actionRef = useRef<ActionType>();

  const TableElement = () => {
    return (
      <ProTable<T>
        columns={columns}
        actionRef={actionRef}
        cardBordered
        request={async (params, sortParams) => {
          const sort = Object.keys(sortParams).map((key) => `${key}:` + (sortParams[key] === 'descend' ? 'desc' : 'asc') ).join(',');
          const page = params.current;
          const size = params.pageSize;
          delete params.current;
          delete params.pageSize;
          const data = {
            ...params,
            sort: sort === '' ? undefined : sort,
            page,
            size,
          }
          const resp = await listRequest(data);
          return resp.data;
        }}
        editable={{
          type: 'multiple',
        }}
        columnsState={{
          persistenceKey: 'pro-table-singe-demos',
          persistenceType: 'localStorage',
          defaultValue: {
            option: { fixed: 'right', disable: true },
          },
          onChange(value) {
            console.log('value: ', value);
          },
        }}
        rowKey="id"
        search={{
          labelWidth: 'auto',
        }}
        options={{
          setting: {
            listsHeight: 400,
          },
        }}
        form={{
          syncToUrl: (values, type) => {
            if (type === 'get') {
              return {
                ...values,
                created_at: [values.startTime, values.endTime],
              };
            }
            return values;
          },
        }}
        pagination={{
          pageSize: 20,
          onChange: (page) => console.log(page),
        }}
        dateFormatter="string"
        headerTitle={tableTitle}
        toolBarRender={toolBarRender}
      />
    )
  }

  return {TableElement, actionRef}
}

export type CommonProTableProps<T> = {
  tableTitle: string,
  customCols: ProColumns<T>[],
  operationRender: (record: T, index: number, action: ProCoreActionType | undefined) => React.ReactNode[],
  showForm: (id:string|null, onClose: any) => any,
  deleteRequest: (id:string) => any,
  listRequest: (data:any) => any
}

export function useCommonProTable<T extends IdInfo>(
  props: CommonProTableProps<T>
) {
  const {tableTitle, customCols, operationRender, showForm, deleteRequest, listRequest} = props;
  const deleteRecord = async (id: string, action: ProCoreActionType|undefined) => {
    const resp = await deleteRequest(id);
    if (resp.success) {
      message.success('操作成功');
      action?.reload();
      return true;
    }
    message.error('操作失败');
    return false;
  }


  const resultObj = useProTable({
    tableTitle,
    customCols, listRequest,
    operationRender: (dom: ReactNode, record: T, index: number, action: ProCoreActionType | undefined) => [
      ...operationRender(record, index, action),
      <Button size='small' key='edit' onClick={() => showForm(record.id, async () => await action?.reload())}>编辑</Button>,
      <Popconfirm
        title="删除确认"
        description="您确定要删除吗？"
        okText="Yes"
        cancelText="No"
        key="del"
        onConfirm={() => deleteRecord(record.id, action)}
      >
        <Button danger size='small'>删除</Button>
      </Popconfirm>,
    ],
    toolBarRender: () => [
      <Button
        key="button"
        icon={<PlusOutlined />}
        onClick={async () => {
          await showForm(null, async () => await resultObj.actionRef.current?.reload());
        }}
        type="primary"
      >
        新建
      </Button>,
    ],
  }
  )

  return resultObj;
}